package qr.game.rest;

import java.util.List;

import org.simpleframework.xml.core.Persister;

import qr.core.*;

import android.os.StrictMode;
import android.util.Log;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.UniformInterfaceException;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.spi.service.ServiceFinder;

public class RestClient {
	private static final RestClient CLIENT = new RestClient("qr.zberger.com", 8080);
	private String ipAddress;
	private int port;
	private String baseUri;
	private String protocol;
	private Client client;
	private Persister serializer;

	public static RestClient getRestClient(){
		return CLIENT;
	}
	
	private RestClient(String ipAddress, int port) {
		this.ipAddress = ipAddress;
		this.port = port;
		this.protocol = "http://";
		this.baseUri = protocol + this.ipAddress + ":" + this.port;
		serializer = new Persister();

		StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
		StrictMode.setThreadPolicy(policy);
		ServiceFinder.setIteratorProvider(new AndroidServiceIteratorProvider());
		client = Client.create();
		client.setFollowRedirects(true);
	}

	/**
	 * GET Method Returns Game Information
	 * 
	 */
	public Game getGameInfo() {
		WebResource r = client.resource(baseUri + "/game");
		Game castedResponse = null;
		try { 
			String response = r.get(String.class);
			castedResponse = serializer.read(Game.class, response);
		} catch ( UniformInterfaceException ue ) {
			ClientResponse errorResponse = ue.getResponse();
			System.err.println("Get game info failed");		
		} catch (Exception e) {
			e.printStackTrace();
		}
		return castedResponse;
	}

	/**
	 * GET Method Returns Leaderboard Data
	 * 
	 */
	public Leaderboard getLeaderboard() {
		WebResource r = client.resource(baseUri + "/game/leaderboard");
		String response = null;
		Leaderboard castedResponse = null;
		try { 
			response = r.get(String.class);
			castedResponse = serializer.read(Leaderboard.class, response);
		} catch ( UniformInterfaceException ue ) {
			ClientResponse errorResponse = ue.getResponse();
			System.err.println("Get leaderboard info failed");		
		} catch (Exception e) {
			e.printStackTrace();
		}
		return castedResponse;
	}

	/**
	 * GET Method Returns list of all locations
	 * 
	 */
	public List<Location> getLocations() {
		WebResource r = client.resource(baseUri + "/game/location");
		String response = null;
		LocationList castedResponse = null;
		try { 
			response = r.get(String.class);
			castedResponse = serializer.read(LocationList.class, response);
		} catch ( UniformInterfaceException ue ) {
			ClientResponse errorResponse = ue.getResponse();
			System.err.println("Get locations failed");		
		}catch(Exception e){
			e.printStackTrace();
		}
		Log.d("getLocations()", castedResponse.c.size()+"" );
		return castedResponse.c;
	}

	/**
	 * POST Method Registers a new user
	 * 
	 */
	public boolean registerUser(String userId) {
		WebResource r = client.resource(baseUri + "/game/users/" + userId);
		ClientResponse response = null;
		try { 
			response = r.post(ClientResponse.class);
			return true;
		} catch ( UniformInterfaceException ue ) {
			ClientResponse errorResponse = ue.getResponse();
			System.err.println("Enter location failed");	
			return false;
		} 
	}

	/**
	 * GET Method Gets information about a single location.
	 */
	public Location getLocationInfo(String locationId) {
		WebResource r = client.resource(baseUri + "/game/location/" + locationId);
		Location response = null;
		String stringResponse = null;
		try { 
			stringResponse = r.get(String.class);
			response = serializer.read(Location.class, stringResponse);
		} catch ( UniformInterfaceException ue ) {
			ClientResponse errorResponse = ue.getResponse();
			System.err.println("Get lacation info failed");		
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return response;
	}

	/**
	 * GET Method Get's a user's found locations
	 */
	public List<Location> getFoundLocations(String userId) {
		WebResource r = client.resource(baseUri + "/game/" + userId + "/locations");
		LocationList response = null;
		try { 
			String stringResponse = r.get(String.class);
			response = serializer.read(LocationList.class, stringResponse);
		} catch ( UniformInterfaceException ue ) {
			ClientResponse errorResponse = ue.getResponse();
			System.err.println("Get locations failed");		
		}catch(Exception e){
			e.printStackTrace();
		}
		
		return response.c;
	}

	/**
	 * POST Method Enters a location for specified user.
	 */
	public boolean enterLocation(String userId, String qrId) {
		WebResource r = client.resource(baseUri + "/game/location/" + userId);
		ClientResponse response = null;
		try { 
			response = r.post(ClientResponse.class , qrId);
			return response.getStatus() == ClientResponse.Status.CREATED.getStatusCode();
		} catch ( UniformInterfaceException ue ) {
			ClientResponse errorResponse = ue.getResponse();
			System.err.println("Enter location failed");	
			return false;
		}
	}

}
